package com.twang.stock.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.twang.stock.entity.*;
import com.twang.stock.mapper.CompanyStockMinutesMapper;
import com.twang.stock.mapper.ReDianHotRankMapper;
import com.twang.stock.mapper.ThsReDianStockMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.service.ThsReDianStockService;
import com.twang.stock.service.ZhangTingBanService;
import com.twang.stock.task.QueryBanKuaiAndDaPan;
import com.twang.stock.service.ZhangTingBanTaskService;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.HolidayCopy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 *
 */
@Service
@Slf4j
public class ThsReDianStockServiceImpl implements ThsReDianStockService {
    @Resource
    private ThsReDianStockMapper thsReDianStockMapper;
    @Resource
    private ReDianHotRankMapper reDianHotRankMapper;

    @Resource
    private CompanyStockMinutesMapper companyStockMinutesMapper;

    @Resource
    private ZhangTingBanService zhangTingBanService;

    @Autowired
    private ZhangTingBanTaskService zhangTingBanTaskService;

    @Autowired
    private RedisUtil redisUtil;

    public  static String key="getReDianHotRank";

    public  static String key_24Hours="getReDianHotRank_key_24Hours";


    public  static String keyForThS="setCompanyStockMinutes";

    @Autowired
    private AsycTaskExecutorConfig asycTaskExecutorConfig;



    @Override
    public List<BigDecimal> getQueryDataHistory(List<String> days,String code,String type) {
        List<ThsReDianStock> results = thsReDianStockMapper.selectByCode(code, type);
        List<BigDecimal>  orders= Lists.newArrayList();
        results.forEach(item->{
           String dateTime= HolidayCopy.getHHmmss(item.getCreateTime());
            days.add(dateTime);
            orders.add(new BigDecimal(100).subtract(item.getStockOrder()));
        });
        return orders;
    }

    @Override
    public void getThsHotStockList(List<ThsReDianStock> list,List<ThsHotStock> thsHotStockList){
        for(int i=0;i<100;i++){
            ThsReDianStock thsReDianStock= list.get(i);
            ThsHotStock item=new ThsHotStock();
            BeanUtils.copyProperties(thsReDianStock,item);
            item.setZhangdie(thsReDianStock.getZhangDie());
            item.setOrder(thsReDianStock.getStockOrder().intValue());
            if(StringUtils.isNotBlank(thsReDianStock.getSustainTags())){
                item.setSustainTags(JSONObject.parseArray(thsReDianStock.getSustainTags(), ThsGeGuReZDianSustainTags.class));
            }
            if(StringUtils.isNotBlank(thsReDianStock.getTag())){
                item.setTag(JSONObject.parseObject(thsReDianStock.getTag(), ThsHotStock.ThsHotStockTag.class));
            }
            thsHotStockList.add(item);
        }
    }

    @Override
    public List<DfcfBanKuaiMaoLiLv> getReDianHotRank(Boolean isCache) throws Exception {
        if(isCache) {
            Object obj = redisUtil.get(key + HolidayCopy.getRealToday());
            if (null != obj) {
                List<DfcfBanKuaiMaoLiLv> maoLiLvs = JSONObject.parseArray(obj.toString(), DfcfBanKuaiMaoLiLv.class);
                return maoLiLvs;
            }else{
                getReDianHotRank(Boolean.FALSE);
                //redisUtil.set(key,key,300);
            }
        }
        //
        List<ReDianHotRank> reDianHotRankList = reDianHotRankMapper.getReDianHotRank();
        ConcurrentHashMap<String, ReDianHotRank> 临时记录 = new ConcurrentHashMap<>();
        {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH, -2);
            Date 两天前 = calendar.getTime();
            {
                //删除5天前的记录
                Calendar calendar1 = Calendar.getInstance();
                calendar1.add(Calendar.DAY_OF_MONTH, -2);
                Date 五天前 = calendar.getTime();
                Integer id = reDianHotRankMapper.getDeletedId(五天前);
                log.info(">>>>>>>>>>>>>> getReDianHotRank 五天前的ID={}", id);
                if (id.intValue() > 0) {
                   int num= reDianHotRankMapper.deletedData(Long.valueOf(id));
                    log.info(">>>>>>>>>>>>>> getReDianHotRank 删除数量={}", num);
                }
            }
            // 遍历股票数据并计算值
            List<ReDianHotRank> codesList = reDianHotRankMapper.queryCodes();
            codesList.stream().forEach(item -> {
                try {
                    多线程处理数据(临时记录, item, 两天前);
                } catch (Exception e) {
                    log.error("E={}", e);
                }
            });

            log.info(">>>>>>>>>>>>>> getReDianHotRank 遍历股票数据并计算值 临时记录={}", JSONObject.toJSONString(临时记录));
            // 将 Map 的值转换为列表
            List<ReDianHotRank> 临时记录列表 = new ArrayList<>(临时记录.values());

            // 按 rankIncrease 排序
            Collections.sort(临时记录列表, Comparator.comparing(ReDianHotRank::getRankIncrease).reversed());

            // 显示记录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            reDianHotRankList.clear();
            for (ReDianHotRank 记录 : 临时记录列表) {
                reDianHotRankList.add(记录);
            }
        }

        return getBanKuaiMaoLiLvs(reDianHotRankList,key);
    }

    /**
     *
     * @param reDianHotRankList
     * @return
     */
    private List<DfcfBanKuaiMaoLiLv> getBanKuaiMaoLiLvs(List<ReDianHotRank> reDianHotRankList,String cacheKey) {
        List<DfcfBanKuaiMaoLiLv> daceBanKaiMaoLiLvList = Lists.newArrayList();
        reDianHotRankList.forEach(item -> {
            try {
                this.setCompanyStockMinutes(item, daceBanKaiMaoLiLvList);
            } catch (Exception e) {
                log.error(">>>>>>>>>>>> getBanKuaiMaoLiLvs{}", e);
            }
        });
        //
        zhangTingBanTaskService.initKanDian(daceBanKaiMaoLiLvList, Boolean.FALSE);
        //30 Min 成交额
        zhangTingBanTaskService.getTrade30MinutesVol(daceBanKaiMaoLiLvList);
        Object obj=redisUtil.get(cacheKey+HolidayCopy.getRealToday());
        if (null != obj) {
            List<DfcfBanKuaiMaoLiLv> maoLiLvs = JSONObject.parseArray(obj.toString(), DfcfBanKuaiMaoLiLv.class);
            maoLiLvs.addAll(daceBanKaiMaoLiLvList);
            //去重
            maoLiLvs=maoLiLvs.stream().distinct().collect(Collectors.toList());
            redisUtil.set(cacheKey + HolidayCopy.getRealToday(), JSONObject.toJSONString(maoLiLvs),60*60*24);
            return maoLiLvs;
        }else{
            redisUtil.set(cacheKey+HolidayCopy.getRealToday(), JSONObject.toJSONString(daceBanKaiMaoLiLvList),60*60*24);
        }
        return daceBanKaiMaoLiLvList;
    }

    private void 多线程处理数据(ConcurrentHashMap<String, ReDianHotRank> 临时记录, ReDianHotRank 记录1,Date date) {
        ReDianHotRank max = reDianHotRankMapper.getMax(记录1.getCode(),date).get(0);
        ReDianHotRank min = reDianHotRankMapper.getMin(记录1.getCode(),date).get(0);
        Integer maxRank = 100 - max.getStockOrder().intValue();
        Integer minRank = 100 - min.getStockOrder().intValue();
        BigDecimal rankIncrease = new BigDecimal(maxRank - minRank);
        if (max.getCreateTime().before(min.getCreateTime())) {
            rankIncrease = rankIncrease.multiply(new BigDecimal(-1));
        }
        log.info(">>>>>>>>>>>>>> getReDianHotRank 比较开始 name={}  max={}  min={}  增长={}", max.getName(), maxRank, minRank, rankIncrease);
        if (rankIncrease.intValue() > 20||rankIncrease.intValue()< -20) {
            ReDianHotRank reDianHotRank = new ReDianHotRank();
            reDianHotRank.setName(max.getName());
            reDianHotRank.setCode(max.getCode());
            reDianHotRank.setRankIncrease(rankIncrease);
            reDianHotRank.setMinRank(new BigDecimal(minRank));
            reDianHotRank.setMaxRank(new BigDecimal(maxRank));
            reDianHotRank.setStartTime(max.getCreateTime());
            reDianHotRank.setEndTime(min.getCreateTime());
            if(rankIncrease.intValue()>0){
                reDianHotRank.setIncreaseType(1);
            }else{
                reDianHotRank.setIncreaseType(0);
            }
            临时记录.put(max.getCode(), reDianHotRank);
        }
    }

    /**
     * 初始化所有参数
     * @param item
     * @param dfcfBanKuaiMaoLiLvList
     */
    private void setCompanyStockMinutes(ReDianHotRank item, List<DfcfBanKuaiMaoLiLv> dfcfBanKuaiMaoLiLvList) throws Exception {
        DfcfBanKuaiMaoLiLv dfcfBanKuaiMaoLiLv = new DfcfBanKuaiMaoLiLv();
        dfcfBanKuaiMaoLiLv.setCode(item.getCode());
        dfcfBanKuaiMaoLiLv.setName(item.getName());
        String code = item.getCode();
        if (code.startsWith("6")) {
            code = "sh" + code;
        } else {
            code = "sz" + code;
        }
        CompanyStockMinutes companyStockMinutes = companyStockMinutesMapper.queryByCode(code);
        if (null == companyStockMinutes) {
            throw new Exception("setCompanyStockMinutes -->未查询到 companyStockMinutes"+code);
        }
        //涨跌
        dfcfBanKuaiMaoLiLv.setMll(companyStockMinutes.getZhangDie());
        dfcfBanKuaiMaoLiLv.setCje(companyStockMinutes.getTradeSum());
        String setCompanyStockMinutesKey = keyForThS + "_" + item.getCode() + "_" + HolidayCopy.getRealToday();
        try {
            Object object = redisUtil.get(setCompanyStockMinutesKey);
            List<ThsGeGuReZDian> thsGeGuReZDianList = null;
            if (null == object) {
                thsGeGuReZDianList = QueryBanKuaiAndDaPan.查询个股热点(item.getCode());
                //查询涨停原因
                {
                    ThsGeGuReZDian thsGeGuReZDian = new ThsGeGuReZDian();
                    thsGeGuReZDian.setTagName("历史涨停原因");
                    String ztDesc = zhangTingBanService.zhangtingReason(code);
                    if (StringUtils.isNotBlank(ztDesc)) {
                        thsGeGuReZDian.setZtDesc(ztDesc);
                    }
                    thsGeGuReZDianList.add(thsGeGuReZDian);
                }
                redisUtil.set(setCompanyStockMinutesKey,JSONObject.toJSONString(thsGeGuReZDianList), 60 * 60 * 24);
            } else {
                thsGeGuReZDianList = JSONObject.parseArray(object.toString(), ThsGeGuReZDian.class);
            }
            dfcfBanKuaiMaoLiLv.setKanDian(thsGeGuReZDianList);
            dfcfBanKuaiMaoLiLv.setReDianHotRank(item);
        } catch (Exception e) {
            e.printStackTrace();
        }
        dfcfBanKuaiMaoLiLvList.add(dfcfBanKuaiMaoLiLv);
    }

    /**
     * 初始化所有参数
     */
    @Override
    public DfcfBanKuaiMaoLiLv stockComon(String stockCode, String stockName) throws Exception {
        DfcfBanKuaiMaoLiLv dfcfBanKuaiMaoLiLv = new DfcfBanKuaiMaoLiLv();
        dfcfBanKuaiMaoLiLv.setCode(stockCode);
        dfcfBanKuaiMaoLiLv.setName(stockName);
        String code = stockCode;
        if (code.startsWith("6")) {
            code = "sh" + code;
        } else {
            code = "sz" + code;
        }
        CompanyStockMinutes companyStockMinutes = companyStockMinutesMapper.queryByCode(code);
        if (null == companyStockMinutes) {
            throw new Exception("setCompanyStockMinutes -->未查询到 companyStockMinutes:"+code);
        }
        //涨跌
        dfcfBanKuaiMaoLiLv.setMll(companyStockMinutes.getZhangDie());
        dfcfBanKuaiMaoLiLv.setCje(companyStockMinutes.getTradeSum());
//        String setCompanyStockMinutesKey = keyForThS + "_" + stockCode + "_" + HolidayCopy.getRealToday();
//        try {
//            Object object = redisUtil.get(setCompanyStockMinutesKey);
//            List<ThsGeGuReZDian> thsGeGuReZDianList = null;
//            if (null == object) {
//                thsGeGuReZDianList = QueryBanKuaiAndDaPan.查询个股热点(stockCode);
//                //查询涨停原因
//                {
//                    ThsGeGuReZDian thsGeGuReZDian = new ThsGeGuReZDian();
//                    thsGeGuReZDian.setTagName("历史涨停原因");
//                    String ztDesc = zhangTingBanService.zhangtingReason(code);
//                    if (StringUtils.isNotBlank(ztDesc)) {
//                        thsGeGuReZDian.setZtDesc(ztDesc);
//                    }
//                    thsGeGuReZDianList.add(thsGeGuReZDian);
//                }
//                redisUtil.set(setCompanyStockMinutesKey,JSONObject.toJSONString(thsGeGuReZDianList));
//            } else {
//                thsGeGuReZDianList = JSONObject.parseArray(object.toString(), ThsGeGuReZDian.class);
//            }
//            dfcfBanKuaiMaoLiLv.setKanDian(thsGeGuReZDianList);
//        } catch (Exception e) {
//            log.error("",e);
//            e.printStackTrace();
//        }
       return dfcfBanKuaiMaoLiLv;
    }

    @Override
    public List<DfcfBanKuaiMaoLiLv> select24HourData(Boolean isCache) throws Exception {
        if(isCache) {
            Object obj = redisUtil.get(key_24Hours + HolidayCopy.getRealToday());
            if (null != obj) {
                List<DfcfBanKuaiMaoLiLv> maoLiLvs = JSONObject.parseArray(obj.toString(), DfcfBanKuaiMaoLiLv.class);
                return maoLiLvs;
            }else{
                select24HourData(Boolean.FALSE);
            }
        }
        List<ThsReDianStock> list = thsReDianStockMapper.select24HourData();
        List<ReDianHotRank> reDianHotRankList = new ArrayList<>();
        for (ThsReDianStock item : list) {
            ReDianHotRank reDianHotRank = new ReDianHotRank();
            reDianHotRank.setCode(item.getCode());
            reDianHotRank.setName(item.getName());
            reDianHotRank.setRankIncrease(item.getStockOrder());
            reDianHotRankList.add(reDianHotRank);
        }
        return getBanKuaiMaoLiLvs(reDianHotRankList,key_24Hours);
    }
}
